# vim: set cindent expandtab ts=4 sw=4:
#
# Copyright (c) 1998-2005 Chi-Keung Ho. All rights reserved.
#
# This programe is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# ExtMan - web interface to manage virtual accounts
# $Id$
use strict;
use DBI;

package DB;
use Exporter;
use Passwd;
#use Ext::Mgr;
use POSIX qw(strftime);
use vars qw(@ISA @EXPORT);
@EXPORT = qw(auth);

sub new {
    my $this = shift;
    my $self = bless {@_}, ref $this || $this;
    $self->init(@_);
    $self;
}

sub init {
    my $self = shift;
    my %opt = @_;

    $opt{host} = '127.0.0.1' if not defined $opt{host};
    $opt{dbname} = 'extsender' if not defined $opt{dbname};
    $opt{dbuser} = 'extsender' if not defined $opt{dbuser};
    $opt{dbpw} = 'extsender' if not defined $opt{dbpw};

    $self->{opt}=\%opt;

    my $connect = "DBI:mysql:database=$opt{dbname};host=$opt{host}";
    if ($opt{socket}) {
        $connect .= ";mysql_socket=$opt{socket}";
    }
    my $dbh = DBI->connect(
        $connect,$opt{dbuser}, $opt{dbpw}, {'RaiseError' => 0}
    );

    $self->{dbh} = $dbh;
#    $self->{psize} = $opt{psize} || 10;
#    $self->{crypt_type} = $opt{crypt_type} || 'crypt'; # default type
}

sub search_username {
    my $self = shift;
    my $filter = $_[0];
    my %res = ();
    my $username = "username";
    my $SQL = "SELECT * FROM user WHERE $username='$filter'";
    my $sth = $self->{dbh}->prepare($SQL);

    $sth->execute();
    while(my $r=$sth->fetchrow_hashref()) {
        $res{$r->{$username}} = $r; # feedback all rows
    };
    $sth->finish();
    \%res; # return a REF
}

sub verify {
    return 1;
}

sub auth {
    my $self = shift;
    my ($username, $password) = (@_);
    my $res = $self->search_username($username);

    if(scalar keys %$res) {
        my $pwd = $res->{$username}->{password};

        # this step is a must, or null userpassword record will cause hole
        # that anonymous can step in the system
        return 0 unless($password && $pwd);

        if($self->verify($password, $pwd)) {
            $self->{INFO} = $self->_fill_user_info($res->{$username});
            return 1;
        }else {
            return 0;
        }
    }

    0; # default ?:)
}

sub _fill_user_info {
    my $self = shift;
    my $opt = $self->{opt};
    my $entry = $_[0];
    my %info = ();

    # original infomation filling
    foreach my $key (keys %$entry) {
        $info{$key} = $entry->{$key};
    }

    $info{TYPE} = $info{'type'};

    \%info;
}

sub get_entry {
    my $self = shift;
    my $sth = $self->{dbh}->prepare($_[0]);
    $sth->execute();
    $sth->fetchrow_hashref(); # the first entry if multiplies return
}

sub get_entries {
    my $self = shift;
    my $sth = $self->{dbh}->prepare($_[0]);
    my $arr = [];

    $sth->execute();
    while (my $r=$sth->fetchrow_hashref()) {
        push @$arr, $r;
    }
    $arr;
}

#==========================#
# extmailUser land handler #
#==========================#

sub by_username {
    lc $a->{username} cmp lc $b->{username};
}

sub by_queue {
    lc $a->{username} cmp lc $b->{username};
}

sub by_queues {
    lc $a->{username} cmp lc $b->{username};
}

sub get_queues_list {
    my $self = shift;
    my $SQL = "SELECT * FROM queue where status='$_[0]'";
    my $rs = $self->get_entries($SQL);
    my $arr = [];
    foreach my $ref ( sort by_queues @$rs ) {
	push @$arr, {
        	qid => $ref->{qid},
        	username => $ref->{username},
        	insertdate => $ref->{insertdate},
        	startdate => $ref->{startdate},
        	enddate => $ref->{enddate},
        	sender => $ref->{sender},
        	subject => $ref->{subject},
        	headerpath => $ref->{headerpath},
        	templatepath => $ref->{templatepath},
        	rlistpath => $ref->{rlistpath},
        	logpath => $ref->{logpath},
        	status => $ref->{status},
        	success => $ref->{success},
        	faild => $ref->{faild},
        	hardbounce => $ref->{hardbounce},
        	softbounce => $ref->{softbounce},
	}
    }
    scalar @$arr ? $arr : undef;
}

sub get_queue_info {
    my $self = shift;
    my $qid = $_[0];
    #my $domain = $user;

    #$domain =~ s#^([^\@]+)@##;
    my $SQL = "SELECT * FROM queue where qid='$qid'";
    my $ref = $self->get_entry($SQL);
    return undef unless ($ref);
    return {
        qid => $ref->{qid},
        username => $ref->{username},
        insertdate => $ref->{insertdate},
        startdate => $ref->{startdate},
        enddate => $ref->{enddate},
        sender => $ref->{sender},
        subject => $ref->{subject},
        headerpath => $ref->{headerpath},
        templatepath => $ref->{templatepath},
        rlistpath => $ref->{rlistpath},
        logpath => $ref->{logpath},
        status => $ref->{status},
        success => $ref->{success},
        faild => $ref->{faild},
        hardbounce => $ref->{hardbounce},
        softbounce => $ref->{softbounce},
    }
}

sub set_status {
    my $self = shift;
    my $qid = $_[0];
    my $status = $_[1];
    if($qid && $status){
	my $SQL = "UPDATE queue set status='$status' where qid='$qid'";
	my $sth = $self->{dbh}->prepare($SQL);
	$sth->execute;
	$sth->finish();
	return 1;
    }else{
	return 0;
    }
}

sub ext_info {
    my $self = shift;
    return $self->{_ext_info};
}

sub DESTORY {
    my $self = shift;
    $self->{dbh}->disconnect();
    undef $self;
}
1;
